﻿using DeploySources.Helper;
using DeploySources.MVVM;
using Microsoft.SharePoint.Client;
using Sources;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using DeploySources.View;
using System;

namespace DeploySources.ViewModel
{
	/// <summary>
	/// ViewModel for EnsureData View
	/// </summary>
	public class EnsureDataViewModel : BaseViewModel
	{
		private ClientContext _context;

		/// <summary>
		/// Constructor
		/// </summary>
		public EnsureDataViewModel()
		{
			Mediator.Register("IsConnected", Connected);
		}
		
		/// <summary>
		/// Method for mediator notifications
		/// </summary>
		/// <param name="args">command parameters</param>
		private void Connected(object args)
		{
			var connectionParameter = (ConnectedParameter)args;

			IsConnected = connectionParameter.IsConnected;
			_context = connectionParameter.Context;

			if (IsConnected)
			{
				Sources.Helper.LoadArtefacts(connectionParameter.Connection.ArtefactFile);

				ShowArtefacts();
			}
		}

		/// <summary>
		/// Show all Artefacts
		/// </summary>
		private void ShowArtefacts()
		{
			if (Sources.Helper.GetFields != null)
			{
				_fields = new ObservableCollection<FieldArtefact>(Sources.Helper.GetFields.Invoke(null, null) as List<FieldArtefact>);
				OnPropertyChanged("Fields");
			}

			if (Sources.Helper.GetContentTypes != null)
			{
				_contentTypes = new ObservableCollection<ContentTypeArtefact>(Sources.Helper.GetContentTypes.Invoke(null, null) as List<ContentTypeArtefact>);
				OnPropertyChanged("ContentTypes");
			}

			if (Sources.Helper.GetLists != null)
			{
				_lists = new ObservableCollection<ListArtefact>(Sources.Helper.GetLists.Invoke(null, null) as List<ListArtefact>);
				OnPropertyChanged("Lists");
			}
		}

		private bool _isConnected;
		/// <summary>
		/// IsConnected is bound to the view and controls the enabled state for the controls
		/// </summary>
		public bool IsConnected
		{
			get { return _isConnected; }
			set
			{
				_isConnected = value;
				OnPropertyChanged("IsConnected");
			}
		}

		private ObservableCollection<FieldArtefact> _fields;
		/// <summary>
		/// Fields to display in the View
		/// </summary>
		public ObservableCollection<FieldArtefact> Fields
		{
			get
			{
				if (_fields == null)
				{
					_fields = new ObservableCollection<FieldArtefact>();
				}
				return _fields;
			}
		}

		private ObservableCollection<ContentTypeArtefact> _contentTypes;
		/// <summary>
		/// Contenttypes to display in the View
		/// </summary>
		public ObservableCollection<ContentTypeArtefact> ContentTypes
		{
			get
			{
				if (_contentTypes == null)
				{
					_contentTypes = new ObservableCollection<ContentTypeArtefact>();
				}
				return _contentTypes;
			}
		}

		private ObservableCollection<ListArtefact> _lists;
		/// <summary>
		/// Lists to display in the View
		/// </summary>
		public ObservableCollection<ListArtefact> Lists
		{
			get
			{
				if (_lists == null)
				{
					_lists = new ObservableCollection<ListArtefact>();
				}
				return _lists;
			}
		}

		private RelayCommand _ensureAllCommand;
		/// <summary>
		/// Deploy all fields command
		/// </summary>
		public RelayCommand EnsureAllCommand => _ensureAllCommand ?? (_ensureAllCommand = new RelayCommand(
			                                              param => DeployItems(param as IEnumerable<IDeployableObject>)
		                                              ));

		private RelayCommand _updateAllCommand;
		/// <summary>
		/// Update all fields command
		/// </summary>
		public RelayCommand UpdateAllCommand => _updateAllCommand ?? (_updateAllCommand = new RelayCommand(
														  param => UpdateItems(param as IEnumerable<IDeployableObject>)
													  ));

		private RelayCommand _rebindAllCommand;
		/// <summary>
		/// Rebind all fields command
		/// </summary>
		public RelayCommand RebindAllCommand => _rebindAllCommand ?? (_rebindAllCommand = new RelayCommand(
														  param => RebindItems(param as IEnumerable<IDeployableObject>)
													  ));

		private RelayCommand _ensureCommand;
		/// <summary>
		/// Deploy a single field command
		/// </summary>
		public RelayCommand EnsureCommand => _ensureCommand ?? (_ensureCommand = new RelayCommand(
			                                          param => DeployItem(param as IDeployableObject)
		                                          ));

		private RelayCommand _updateCommand;
		/// <summary>
		/// Deploy a single field command
		/// </summary>
		public RelayCommand UpdateCommand => _updateCommand ?? (_updateCommand = new RelayCommand(
													  param => UpdateItem(param as IDeployableObject)
												  ));

		private RelayCommand _rebindCommand;
		/// <summary>
		/// Deploy a single field command
		/// </summary>
		public RelayCommand RebindCommand => _rebindCommand ?? (_rebindCommand = new RelayCommand(
													  param => RebindItem(param as IDeployableObject)
												  ));
		
		/// <summary>
		/// Deploy a single item
		/// </summary>
		/// <param name="item">Item to Deploy</param>
		private void DeployItem(IDeployableObject item)
		{
			DeployItems(Enumerable.Repeat(item, 1));
		}

		/// <summary>
		/// Deploy a List of items
		/// </summary>
		/// <param name="items">Items to deploy</param>
		private void DeployItems(IEnumerable<IDeployableObject> items)
		{
			var wv = new WorkerView(_context, items)
			{
				Owner = Application.Current.MainWindow,
				WindowStartupLocation = WindowStartupLocation.CenterOwner
			};
			wv.ShowDialog();
		}

		/// <summary>
		/// Update a single item
		/// </summary>
		/// <param name="item">Item to Deploy</param>
		private void UpdateItem(IDeployableObject item)
		{
			UpdateItems(Enumerable.Repeat(item, 1));
		}

		/// <summary>
		/// Update a List of items
		/// </summary>
		/// <param name="items">Items to deploy</param>
		private void UpdateItems(IEnumerable<IDeployableObject> items)
		{
			//var wv = new WorkerView(_context, items)
			//{
			//	Owner = Application.Current.MainWindow,
			//	WindowStartupLocation = WindowStartupLocation.CenterOwner
			//};
			//wv.ShowDialog();
		}

		/// <summary>
		/// Rebind a single item
		/// </summary>
		/// <param name="item">Item to Deploy</param>
		private void RebindItem(IDeployableObject item)
		{
			RebindItems(Enumerable.Repeat(item, 1));
		}

		/// <summary>
		/// Rebind a List of items
		/// </summary>
		/// <param name="items">Items to deploy</param>
		private void RebindItems(IEnumerable<IDeployableObject> items)
		{
			//var wv = new WorkerView(_context, items)
			//{
			//	Owner = Application.Current.MainWindow,
			//	WindowStartupLocation = WindowStartupLocation.CenterOwner
			//};
			//wv.ShowDialog();
		}
	}
}
